package co.fitstart.mobile.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.persistence.GenericDaoSupport;
import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.course.schedule.ScheduleStatus;
import co.fitstart.entity.courseware.fitnessgroup.BatchCourseware;
import co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType;
import co.fitstart.entity.courseware.fitnessgroup.Courseware;
import co.fitstart.entity.courseware.fitnessgroup.CoursewareEditStatus;
import co.fitstart.entity.courseware.fitnessgroup.DailyCourseware;
import co.fitstart.mobile.dao.support.ScheduleDaoSupport;
import co.fitstart.mobile.service.CoursewareService;

/**
 * 
 * @author mohanlan
 *
 */
@Service("coursewareService")
public class CoursewareServiceImpl implements CoursewareService {
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Autowired
    private ScheduleDaoSupport scheduleDaoSupport;


    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#listGeneratedCourseware(co.fitstart.entity.course.round.CourseRound, co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType)
     */
    @SuppressWarnings("unchecked")
    public List<BatchCourseware> listGeneratedCourseware(CourseRound courseRound, BatchCoursewareType type) {
        
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("courseRound", courseRound);
        parameters.put("type", type);
        parameters.put("editStatus", CoursewareEditStatus.GENERATED);
        
        return genericDaoSupport.searchForList("FROM BatchCourseware WHERE courseRound = :courseRound AND "
                                                                        + "type = :type AND "
                                                                        + "editStatus = :editStatus AND "
                                                                        + "disabled = false"
                                                                        + " ORDER BY sorting ASC", parameters);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#listBatchCourseware(co.fitstart.entity.course.round.CourseRound, co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType)
     */
    @SuppressWarnings("unchecked")
    public List<BatchCourseware> listBatchCourseware(CourseRound courseRound, BatchCoursewareType type) {
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("courseRound", courseRound);
        parameters.put("type", type);
        
        return genericDaoSupport.searchForList("FROM BatchCourseware WHERE courseRound = :courseRound AND "
                                                                        + "type = :type AND "
                                                                        + "disabled = false"
                                                                        + " ORDER BY sorting ASC", parameters);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#listGeneratedCourseware(co.fitstart.entity.courseware.fitnessgroup.BatchCourseware)
     */
    @SuppressWarnings("unchecked")
    public List<DailyCourseware> listGeneratedCourseware(BatchCourseware batchCourseware) {
        return genericDaoSupport.searchForList("FROM DailyCourseware WHERE batch = :batch AND editStatus = 2 AND disabled = false ORDER BY sorting ASC", "batch", batchCourseware);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#loadGeneratedCourseware(co.fitstart.entity.course.round.CourseRound, co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType, int)
     */
    public BatchCourseware loadGeneratedCourseware(CourseRound courseRound, BatchCoursewareType type, int sorting) {
        
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("courseRound", courseRound);
        parameters.put("type", type);
        parameters.put("sorting", sorting);
        parameters.put("editStatus", CoursewareEditStatus.GENERATED);
        
        return genericDaoSupport.searchForObject("FROM BatchCourseware WHERE courseRound = :courseRound AND "
                                                                        + "type = :type AND "
                                                                        + "editStatus = :editStatus AND "
                                                                        + "disabled = false AND "
                                                                        + "sorting = :sorting", parameters, BatchCourseware.class);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#loadBatchCourseware(java.lang.Long)
     */
    public BatchCourseware loadBatchCourseware(Long batchId) {
        return genericDaoSupport.searchForObject("FROM BatchCourseware WHERE id = :id AND disabled = false", "id", batchId, BatchCourseware.class);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#loadDailyCourseware(java.lang.Long)
     */
    public DailyCourseware loadDailyCourseware(Long dailyId) {
        return genericDaoSupport.searchForObject("FROM DailyCourseware WHERE id = :id AND disabled = false", "id", dailyId, DailyCourseware.class);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#getBatchCourseware(co.fitstart.entity.course.round.CourseRound, co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType)
     */
    public BatchCourseware getBatchCourseware(CourseRound courseRound, BatchCoursewareType type) {
        
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("courseRound", courseRound);
        parameters.put("type", type);
        
        BatchCourseware batchCourseware = genericDaoSupport.searchForObject("FROM BatchCourseware WHERE courseRound = :courseRound AND "
                                                                            + "type = :type AND "
                                                                            + "editStatus != 2 AND "
                                                                            + "disabled = false ORDER BY sorting", parameters, BatchCourseware.class);

        
        if(batchCourseware == null) {
            batchCourseware = this.getBatchCourseware(courseRound, type, 1);
        }
        
        return batchCourseware;
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#getBatchCourseware(co.fitstart.entity.course.round.CourseRound, co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType, int)
     */
    public BatchCourseware getBatchCourseware(CourseRound courseRound, BatchCoursewareType type, int sorting) {
        
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("courseRound", courseRound);
        parameters.put("type", type);
        parameters.put("sorting", sorting);
        
        return genericDaoSupport.searchForObject("FROM BatchCourseware WHERE courseRound = :courseRound AND "
                                                                        + "type = :type AND "
                                                                        + "disabled = false AND "
                                                                        + "sorting = :sorting", parameters, BatchCourseware.class);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#getDailyCourseware(co.fitstart.entity.courseware.fitnessgroup.BatchCourseware)
     */
    public DailyCourseware getDailyCourseware(BatchCourseware batchCourseware) {
        
        return genericDaoSupport.searchForObject("FROM DailyCourseware WHERE disabled = false AND batch = :batch AND editStatus != 2 ORDER BY sorting", "batch", batchCourseware, DailyCourseware.class);
        
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#getDailyCourseware(co.fitstart.entity.courseware.fitnessgroup.BatchCourseware, int)
     */
    public DailyCourseware getDailyCourseware(BatchCourseware batchCourseware, int sorting) {
        
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("batch", batchCourseware);
        parameters.put("sorting", sorting);
        
        return genericDaoSupport.searchForObject("FROM DailyCourseware WHERE batch = :batch AND "
                                                                        + "disabled = false AND "
                                                                        + "sorting = :sorting", parameters, DailyCourseware.class);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#listCourseCourseware(co.fitstart.entity.courseware.fitnessgroup.DailyCourseware)
     */
    @SuppressWarnings("unchecked")
    public List<Courseware> listCourseCourseware(DailyCourseware dailyCourseware) {
        return genericDaoSupport.searchForList("FROM Courseware WHERE disabled = false AND daily = :daily ORDER BY type, id", "daily", dailyCourseware);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#listCoursewareByCourseSchedule(co.fitstart.entity.course.schedule.CourseSchedule)
     */
    public List<Courseware> listCoursewareByCourseSchedule(CourseSchedule courseSchedule) {
        BatchCourseware batchCourseware = this.getBatchCourseware(courseSchedule.getCourseRound(), BatchCoursewareType.COURSE, 1);
        
        if(batchCourseware != null) {
            Map<String, Object> parameters = new HashMap<String, Object>();
            parameters.put("courseRound", courseSchedule.getCourseRound());
            parameters.put("scheduleStatus", new ScheduleStatus[]{ScheduleStatus.READY, ScheduleStatus.EXPIRY, ScheduleStatus.FINISH});
            parameters.put("occurDate", courseSchedule.getOccurDate());
            parameters.put("occurHour", courseSchedule.getOccurHour());
            
            int seesion = genericDaoSupport.count("FROM CourseSchedule WHERE disabled=false"
                    + " AND courseRound=:courseRound AND scheduleStatus IN (:scheduleStatus)"
                    + " AND (occurDate<:occurDate OR (occurDate=:occurDate AND occurHour<=:occurHour))", parameters);
            
            DailyCourseware dailyCourseware = this.getDailyCourseware(batchCourseware, seesion);
            
            if(dailyCourseware != null && dailyCourseware.getEditStatus().isGenerated()) {
                return this.listCourseCourseware(dailyCourseware);
            }
        }
        
        return null;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.coach.service.CoursewareService#listCourseSchedule(co.fitstart.entity.course.round.CourseRound)
     */
    public List<CourseSchedule> listCourseSchedule(CourseRound courseRound) {
        return scheduleDaoSupport.listCourseSchedule(courseRound, new ScheduleStatus[]{ScheduleStatus.READY, ScheduleStatus.FINISH, ScheduleStatus.EXPIRY});
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.coach.service.CoursewareService#listCourseWares(co.fitstart.entity.course.schedule.CourseSchedule)
     */
    @SuppressWarnings("unchecked")
    public List<Courseware> listCourseWares(CourseSchedule courseSchedule) {
        return genericDaoSupport.searchForList("FROM Courseware WHERE disabled=false AND courseSchedule=:courseSchedule ORDER BY id ASC", "courseSchedule", courseSchedule);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.mobile.service.CoursewareService#getRank(co.fitstart.entity.course.schedule.CourseSchedule)
     */
    public int getRank(CourseSchedule courseSchedule) {
        return scheduleDaoSupport.getRank(courseSchedule);
    }
}
